package com.neu.controller;


import com.neu.base.Result;
import com.neu.service.MinioService;
import io.minio.messages.Item;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/minio")
@Tag(name = "文件上传")
public class MinioController {


    private final MinioService minioService;


    public MinioController(MinioService minioService) {
        this.minioService = minioService;
    }

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    @Operation(summary = "上传文件")
    public Result<String> uploadFile(@RequestParam("file") MultipartFile file) {
        String url = minioService.uploadFile(file);
        log.info("上传成功，url: {}", url);
        return Result.success(url);
    }

    /**
     * 下载文件
     */
    @GetMapping("/download/{objectName}")
    @Operation(summary = "下载文件")
    public ResponseEntity<byte[]> downloadFile(@PathVariable String objectName) throws IOException {
        //在 Java 8 中使用 try-with-resources 来自动管理资源，确保 InputStream 在完成后被关闭。
        try (InputStream inputStream = minioService.downloadFile(objectName)) {
            byte[] content = toByteArray(inputStream);
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + objectName + "\"")
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(content);
        } catch (Exception e) {
            return ResponseEntity.status(500).build();
        }
    }
    /**
     * 将 InputStream 中的所有字节读取到一个 byte 数组中。
     * 这是 Java 8 中替代 readAllBytes() 方法的实现。
     *
     * @param input 输入流
     * @return 包含所有字节的 byte 数组
     * @throws IOException 如果读取过程中发生错误
     */
    private byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();//创建一个新的 byte 数组输出流
        int nRead;
        byte[] data = new byte[16384]; // 16KB 缓冲区
        while ((nRead = input.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        buffer.flush();//刷新此输出流并强制写出所有缓冲的输出字节
        return buffer.toByteArray();
    }
    /**
     * 删除文件
     */
    @DeleteMapping("/delete/{objectName}")
    @Operation(summary = "删除文件")
    public ResponseEntity<Void> deleteFile(@PathVariable String objectName) {
        minioService.deleteFile(objectName);
        return ResponseEntity.noContent().build();
    }

    /**
     * 列出所有文件
     */
    @GetMapping("/list")
    @Operation(summary = "列出所有文件")
    public ResponseEntity<List<Item>> listFiles() {
        List<Item> items = minioService.listFiles();
        return ResponseEntity.ok(items);
    }
}
